package com.geeguo.ebuilder.client.business.system.role.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.geeguo.ebuilder.client.base.database.annotation.TDS;
import com.geeguo.ebuilder.client.base.tenant.model.DataContext;
import com.geeguo.ebuilder.client.business.system.role.mapper.RoleMapper;
import com.geeguo.ebuilder.client.business.system.role.model.RoleConverter;
import com.geeguo.ebuilder.client.business.system.role.model.RoleEntity;
import com.geeguo.ebuilder.client.business.system.role.model.RoleQuery;
import com.geeguo.ebuilder.client.business.system.role.model.RoleVO;
import com.geeguo.ebuilder.client.business.system.role.service.RoleService;
import com.geeguo.ebuilder.client.business.system.rolewebmodule.service.RoleWebModuleService;
import com.geeguo.ebuilder.core.common.model.vo.PageListVO;
import com.geeguo.ebuilder.core.common.utils.ObjectEqualsHelper;
import com.geeguo.ebuilder.core.common.utils.PageUtils;
import com.geeguo.ebuilder.core.common.utils.SqlHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Slf4j
@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RoleWebModuleService roleWebModuleService;

    @TDS
    @Override
    public PageListVO<RoleVO> list(RoleQuery query, DataContext dataContext) {
        Map<String, Object> params = new HashMap<>();
        if (StringUtils.isNotEmpty(query.getName())) {
            params.put("name", SqlHelper.getFullImplict(query.getName()));
        }
        params.put("tenantCode", dataContext.getTenantCode());
        IPage<RoleEntity> page = roleMapper.list(new Page<>(query.getPageNo(), query.getPageSize()), params);
        List<RoleVO> result = new ArrayList<>();
        if (page.getRecords() != null && !page.getRecords().isEmpty()) {
            for (RoleEntity item : page.getRecords()) {
                result.add(RoleConverter.INSTANCE.convert2VO(item));
            }
        }
        return PageUtils.getPageListVO(page, result);
    }

    @TDS
    @Override
    public List<RoleVO> listAll(DataContext dataContext) {
        LambdaQueryWrapper<RoleEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RoleEntity::getTenantCode, dataContext.getTenantCode());
        List<RoleEntity> data = roleMapper.selectList(queryWrapper);
        List<RoleVO> result = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(data)) {
            for (RoleEntity entity : data) {
                result.add(RoleConverter.INSTANCE.convert2VO(entity));
            }
        }
        return result;
    }

    @TDS
    @Override
    public Set<String> listIdByUser(String userId, DataContext dataContext) {
        return roleMapper.listIdByUser(userId);
    }

    @TDS
    @Override
    public Set<String> listCodeByUser(String userId, DataContext dataContext) {
        return roleMapper.listCodeByUser(userId);
    }

    @TDS
    @Override
    public RoleVO get(String id, DataContext dataContext) {
        RoleEntity result = roleMapper.selectById(id);
        if (result != null) {
            return RoleConverter.INSTANCE.convert2VO(result);
        }
        return null;
    }

    @TDS
    @Override
    public RoleVO getByCode(String code, DataContext dataContext) {
        RoleEntity result = roleMapper.getByCode(code, dataContext.getTenantCode());
        if (result != null) {
            return RoleConverter.INSTANCE.convert2VO(result);
        }
        return null;
    }

    @TDS
    @Override
    public RoleVO getByName(String name, DataContext dataContext) {
        RoleEntity result = roleMapper.getByName(name, dataContext.getTenantCode());
        if (result != null) {
            return RoleConverter.INSTANCE.convert2VO(result);
        }
        return null;
    }

    @TDS
    @Override
    public boolean save(RoleEntity entity, DataContext dataContext) {
        return roleMapper.insert(entity) > 0;
    }

    @TDS
    @Override
    public boolean update(RoleEntity current, RoleEntity old, DataContext dataContext) {
        Map<String, Object> changeValues = ObjectEqualsHelper.equals(current, old, new String[]{"code", "name", "remark"});
        if (changeValues.isEmpty()) {
            return true;
        } else {
            changeValues.put("id", current.getId());
            changeValues.put("modifyTime", current.getModifyTime());
            changeValues.put("modifyUser", current.getModifyUser());
            return roleMapper.updateByParams(changeValues) == 1;
        }
    }

    @TDS
    @Override
    @Transactional
    public boolean remove(String id, DataContext dataContext) {
        boolean result = roleMapper.deleteById(id) == 1;
        if (result) {
            roleWebModuleService.removeByRole(id, dataContext);
        }
        return result;
    }

    @TDS
    @Override
    public boolean isUsed(String id, DataContext dataContext) {
        Integer result = roleMapper.isUsed(id);
        return result != null;
    }
}